package zzs.generalframework.java.util.core.classloader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @title
 * @description
 * @project zzs-java-util
 * @package zzs.generalframework.java.util.core.classloader
 * @author zzs
 * @date 2018年2月9日
 * @version 1.0
 */
public class GeneralClassLoader extends ClassLoader
{

	private Logger logger = LoggerFactory.getLogger(GeneralClassLoader.class);

	private final String SUFFIX = ".class";

	private String classpath;

	public GeneralClassLoader(String classpath)
	{
		this.classpath = classpath;
	}

	public GeneralClassLoader(ClassLoader parentClassLoader, String classpath)
	{
		super(parentClassLoader);
		this.classpath = classpath;
	}

	public Class<?> findClass(String className)
	{
		Class<?> clazz = null;
		try
		{
			byte[] classDataByteArray = getClassDateByteArray(className);
			clazz = defineClass(className, classDataByteArray, 0, classDataByteArray.length);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		return clazz;
	}

	/**
	 * 获取类二进制输入流
	 * 
	 * @param className
	 * @return
	 * @throws IOException
	 */
	private byte[] getClassDateByteArray(String className) throws IOException
	{
		InputStream inputStream = null;
		ByteArrayOutputStream byteArrayOutputStream = null;
		String classDataPath = classpath + File.separatorChar + className.replace('.', File.separatorChar) + SUFFIX;
		try
		{
			File classDataFile = new File(classDataPath);
			if(classDataFile.exists())
			{
				inputStream = new FileInputStream(classDataFile);
				byteArrayOutputStream = new ByteArrayOutputStream();
				byte[] buffer = new byte[2048];
				int len = 0;
				while ((len = inputStream.read(buffer)) != -1)
				{
					byteArrayOutputStream.write(buffer, 0, len);
				}
				return byteArrayOutputStream.toByteArray();
			}
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		finally
		{
			inputStream.close();
			byteArrayOutputStream.close();
		}
		return null;
	}

}
